docs(api): document typed StallEventPayload on status.stall.typed SSE event (#4802)#4807
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
β APPROVED β docs(api): document typed StallEventPayload on status.stall.typed SSE event (#4802)
9-gate audit (all passed):
- β Review completed β full diff reviewed, content verified against develop sources
- β No conflicts β mergeable: MERGEABLE
- β CI green β all 4 required status checks pass (lint-pr-title, test ubuntu-22, lint, Analyze/CodeQL); advisory test ubuntu-20 still in progress but non-blocking
- β No regressions β docs-only, no code changes
- βοΈ Unit tests β N/A for docs-only per MEMORY 2026-06-09
- βοΈ E2E/UAT β N/A for docs-only
- β Documented β this IS documentation
- β Security clean β Gitleaks, Trivy, GitGuardian all green; no secrets in diff
- β
Targets
develop
Content accuracy β verified against develop source:
| Claim in docs | Source verified |
|---|---|
6 errorClass enum values |
src/stall-events.ts:35-42 ERROR_CLASS_VALUES β all 6 match exactly (transient_5xx, permission_timeout, jsonl_stall, thinking_stall, unknown_stall, extended_working) |
StallEventPayload field shape (7 fields, types, presence rules) |
src/stall-events.ts:56-78 interface β matches |
statusCode only when errorClass === 'transient_5xx' |
src/stall-events.ts builder validates scope; extractStatusCode returns undefined for non-5xx |
status.stall.typed event name on per-session SSE |
src/events.ts:20 union addition + src/events.ts:380 emitStallTyped body |
toChannelFanoutPayload() strips statusCode (fingerprint-defense) |
src/stall-events.ts:115-120 |
recoveryDisabled per-session kill-switch state |
matches SessionInfo semantics |
Strengths:
- Wire-format example shows every field populated
- Field reference table with type + presence rule + description is exactly what consumers need
errorClassenum table makes the bounded contract unmissable- Channel-fanout fingerprint-defense note is security-aware (operator surfaces vs channels β right call)
- Migration recipe shows the curl+
jqfilter idiom for typed-only subscribers - Backward-compat note preserves the legacy
stallevent as thePath 2 fallback
Scope discipline: 1 file (docs/api-reference.md), +68/-0. No scope creep. Anchor #typed-stall-payload-statusstalltyped matches the auto-generated GitHub slug.
PR body follow-ups (out of scope, acknowledged):
- Global event stream (
GET /v1/events) doesn't emitstatus.stall.typedβ pre-existing minor docs drift noted but untouched, separate cleanup PR if Boss wants it - Channel-side fanout typed variant deferred β not blocking F-9 close scope
Cross-references validated: src/stall-events.ts, src/events.ts, src/stall-detector-typed-emit.ts β all source paths cited in the PR body match the actual files on develop.
Lane: owner-authored PR β bot APPROVE + squash directly per MEMORY 2026-06-21 matrix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documents the new
status.stall.typedSSE event and its typedStallEventPayloadschema introduced by PR #4806 (Issue #4802 F-9 β typed stall payload wiring at every stall-detector emit site).What changed
docs/api-reference.md:status.stall.typedto the Per-Session Events (SSE) event-type list (inline reference at the top of the section).status.stall.typed) subsection covering:StallEventPayloadfield populated.errorClassenum reference (6 values fromERROR_CLASS_VALUES).stallevent still ships in parallel).statusCodestripped for Telegram/Slack/Email viatoChannelFanoutPayload()).stallevent.Why
PR #4806 adds a typed superset of the legacy free-form
stallSSE event. The renderer (PR #4804 dashboard pill + Send continue button) consumes the typed schema, but every external consumer (CLI scripts, third-party integrations, channel transports) needs to know:errorClassenum values (no more free-form string parsing).statusCode(only whenerrorClass === 'transient_5xx').statusCode, channels don't).Without docs, the new event is opaque β consumers can't subscribe or render it correctly.
Aegis version
Developed with: v0.6.7
Cross-references
src/stall-events.ts(typed contract + bounded enum)src/stall-detector-typed-emit.ts(emit helpers)src/events.ts(SessionSSEEventunion +emitStallTypedmethod)Verification
src/stall-events.ts(StallEventPayloadinterface, lines 56-78) βerrorClassenum values againstERROR_CLASS_VALUES(src/stall-events.ts:35-42) βemitStallTypedevent name (status.stall.typed) againstsrc/events.ts:380βSessionSSEEventunion addition againstsrc/events.ts:20-22βtoChannelFanoutPayloadstrip rule againstsrc/stall-events.ts:115-120βextractStatusCode5xx-only validation againstsrc/stall-detector-typed-emit.ts:78-87βPR #4806description (recoveryAttemptsresets on success + idle transition) β#typed-stall-payload-statusstalltypedmatches GitHub's auto-generated slug for### Typed Stall Payload (status.stall.typed)βDiff: 1 file, +68/-0.
Follow-ups (out of scope for this PR)
GET /v1/events) does NOT emitstatus.stall.typedβ the typed variant is exclusively on the per-session stream. Pre-existing minor docs drift (session.stalledlisted vssession_stallin code) is also untouched here β separate cleanup PR if Boss wants it.recoveryExhaustedfield is computed locally by the dashboard fromrecoveryAttemptCount >= recoveryMaxAttempts, not server-emitted. No API surface to document.status.stallwith free-form detail; a follow-up PR can routemeta: toChannelFanoutPayload(payload)throughSessionEventPayload.metafor typed channels. Not blocking β F-9 close scope is the SSE path.